
#include "WTSXSipService/SipSXService.hpp"
#include "WTSXSipService/SipSessionBase.hpp"
#include "WTSXSipService/SipTranSession.hpp"
#include "WTSXSipService/SipServiceUtils.hpp"
#include "WTSXSipService/SipDlgSessionBase.hpp"

#include "WTResipDll/SipUserAgent.hpp"
#include "WTResipDll/SipDebugInfo.hpp"
//#include "resip/stack/PlainContents.hxx"

namespace wtsxsip{


CSipSXService::CSipSXService(): 
m_ua(new wtsip::CSipUserAgent()),
m_ServiceListener(0)
{}


bool CSipSXService::init(const wtsip::SUri& localInfo, const ETransport transport)
{
    try{
        if (!m_ua){
            INFO_LINE("Re-New User Agent.");
            m_ua = new wtsip::CSipUserAgent();
        }
        resip::TransportType rType = CSipServiceUtils::getResipType(transport);

        if (!m_ua->init(rType, localInfo)){
            delete m_ua;
            m_ua = NULL;
            return false;
        }
        m_localInfo = localInfo;
    } catch (std::exception* e)
    {
        return false;
    }
    return true;
}


CSipSXService::~CSipSXService()
{
    if (m_ua){
        m_ua->shutdown();
        delete m_ua;
        m_ua = NULL;
    }
    m_ServiceListener->onDestroy();
}


bool CSipSXService::start()
{
    if (!m_ua)
        return false;

    m_ua->run();
    return true;
}

bool CSipSXService::stop()
{
    if (!m_ua)
        return false;

    m_ua->shutdown();
    return true;
}


///////////////////// Create session methods ///////////////////////

ISipTranSession* CSipSXService::createTranSession(const wtsip::SUri& tar, const wtsip::SUri& local, 
                                           const wtsip::SUri& remote, const wtsip::EMethodTypes mth)
{
    if (!m_ua || m_ua->isShutdown()){
        return NULL;
    }
    wtsip::CapSipMessage msg = m_ua->createRequest(tar, local, remote, mth);
    if (!msg.get()){
        return NULL;
    }
    wtsip::ISipClnTransaction* clnTran = m_ua->createClnTransaction(*msg);
    if (!clnTran){
        return NULL;
    }
    CSipTranSession* pTran = m_sessionMgr.createSession(*clnTran, msg);
    return pTran;
}


ISipDlgSessionBase* CSipSXService::createDlgSession(const wtsip::SUri& tar, 
                                                    const wtsip::SUri& local, 
                                                    const wtsip::SUri& remote,
                                                    const ISipDlgSessionBase::EDlgType type)
{
    if (!m_ua || m_ua->isShutdown()){
        return NULL;
    }
    wtsip::ISipDialogBase* dlg = m_ua->createDialog(local, remote);
    if (!dlg){
        return NULL;
    }
    ISipDlgSessionBase* pDSession = m_sessionMgr.createDlgSession(*dlg, tar, type);
    return pDSession;
}

/////////////////////  Create B2B Session ////////////////////
//
//CSipTranB2bSession* CSipGDService::buildTranB2bSession(CSipTranSession& caller, CSipTranSession& callee)
//{
//    CSipTranB2bSession* b2b = new CSipTranB2bSession(*this, caller, callee);
//    insertB2bSession(b2b);
//    return b2b;
//}
//
//
//CSipInvB2bSession* CSipGDService::buildInvB2bSession(CSipInviteSession& caller, CSipInviteSession& callee)
//{
//    CSipInvB2bSession* b2b = new CSipInvB2bSession(*this, caller, callee);
//    insertB2bSession(b2b);
//    return b2b;
//}
//
//
//CSipSubB2bSession* CSipGDService::buildSubB2bSession(CSipSubscribeSession2& caller, CSipSubscribeSession2& callee)
//{
//    CSipSubB2bSession* b2b = new CSipSubB2bSession(*this, caller, callee);
//    insertB2bSession(b2b);
//    return b2b;
//}


/////////////////  register listener  ///////////////////////////

bool CSipSXService::registerServiceListener(ISipSXServiceListener* listener)
{
    if (!m_ServiceListener){
        m_ServiceListener = listener;
    }
    return true;
}


bool CSipSXService::unregisterServiceListener()
{
    m_ServiceListener = NULL;
    return true;
}


const wtsip::SUri& CSipSXService::getLocalInfo()
{
    return m_localInfo;
}


////////////////   CSipUserAgentListener method /////////////////////////

bool CSipSXService::onRequest(wtsip::ISipDialogBase& dlg, wtsip::ISipSrvTransaction& srv, wtsip::CapSipMessage msg)
{
    ISipTranSession* pTranSession = NULL;
    ISipDlgSessionBase* pDlgSession = m_sessionMgr.createDlgSession(dlg, srv, msg, pTranSession);
    if (!pDlgSession || !pTranSession)
        return false;

    SHeaders headers;
    SMsgBodyBase bodyBase;

    CSipServiceUtils::getHeadersFromExternal(headers, *msg);
    if (msg->getContents()){
        wtsip::CSipWtsipUntils::parseBody(bodyBase.type, bodyBase.subType, bodyBase.contents, msg->getContents());
    }
    if (m_ServiceListener){
        m_ServiceListener->onRequest(*pDlgSession, *pTranSession, headers, bodyBase);
    }
    return true;
}


bool CSipSXService::onRequest(wtsip::ISipSrvTransaction& srv, wtsip::CapSipMessage msg)
{
    ISipTranSession* pTranSession = m_sessionMgr.createSession(srv, msg);
    if (!pTranSession)
        return false;

    SHeaders headers;
    SMsgBodyBase bodyBase;

    CSipServiceUtils::getHeadersFromExternal(headers, *msg);
    if (msg->getContents()){
        wtsip::CSipWtsipUntils::parseBody(bodyBase.type, bodyBase.subType, bodyBase.contents, msg->getContents());
    }
    if (m_ServiceListener){
        m_ServiceListener->onRequest(*pTranSession, headers, bodyBase);
    }
    return true;
}


}//namespace

